package com.power.sifa.approve.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.plf.common.domain.ResponseDTO;
import com.plf.core.base.model.Ha_attachment;
import com.plf.core.base.service.Ha_attachmentService;
import com.plf.core.common.service.BaseServiceImpl;
import com.power.sifa.approve.dao.Apl_arrive_receiptDao;
import com.power.sifa.approve.model.Apl_arrive_detail;
import com.power.sifa.approve.model.Apl_arrive_material;
import com.power.sifa.approve.model.Apl_arrive_receipt;
import com.power.sifa.approve.model.enumeration.St_receipt;
import com.power.sifa.approve.model.pageInfo.Apl_arrive_receiptPageInfo;
import com.power.sifa.approve.service.Apl_arrive_detailService;
import com.power.sifa.approve.service.Apl_arrive_receiptService;
import com.power.sifa.util.CacheHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *  送达回执业务层实现
 */
@Slf4j
@Service
public class Apl_arrive_receiptServiceImpl extends BaseServiceImpl implements Apl_arrive_receiptService {
//    @Resource
//    private Apl_arrive_receiptService service;
    @Resource
    private Apl_arrive_receiptDao dao;
    @Resource
    private CacheHelper cacheHelper;
    @Resource
    private Ha_attachmentService ha_attachmentService;
    @Lazy
    @Resource
    private Apl_arrive_detailService apl_arrive_detailService;

    @Override
    public Apl_arrive_receipt getById(Serializable id) {
        return dao.findById(id).orElse(null);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdate(Apl_arrive_receipt apl_arrive_receipt) {
    	// save 如果数据库不存在这条数据，就会执行保存（即将这条数据插入到数据库）；如果数据库存在这条数据，就会根据主键去更新这条数据
        if (apl_arrive_receipt.getPrimaryKey() != null) {
        	 Apl_arrive_receipt apl_arrive_receiptfDb = dao.findById(apl_arrive_receipt.getPrimaryKey()).orElse(null);
             if(apl_arrive_receiptfDb != null) {
                BeanUtils.copyProperties(apl_arrive_receipt, apl_arrive_receiptfDb);
                dao.save(apl_arrive_receiptfDb);
                return;
             }
        }
        dao.save(apl_arrive_receipt);
    }

    @Override
    public void removeById(Serializable id) {
        dao.deleteById(id);
    }

    @Override
    public Page<Apl_arrive_receipt> findAll(Apl_arrive_receiptPageInfo pageInfo) {
        //排序等定义
        Sort sort;
        if("asc".equals(pageInfo.getOrder())) {
            sort = Sort.by(Sort.Direction.ASC, pageInfo.getSort());
        }else {
            sort = Sort.by(Sort.Direction.DESC, pageInfo.getSort());
        }
        //分页的定义
        Pageable pageable = PageRequest.of(pageInfo.getPageNumber()<=1 ? 0 : pageInfo.getPageNumber()-1, pageInfo.getPageSize(), sort);
        //查询条件
        Specification spec = this.createSpecification(pageInfo);
        return dao.findAll(spec, pageable);
    }

    @Transactional(rollbackFor = Exception.class)
    public void removeByIds(List<Integer> ids) {
        dao.removeByIds(ids);
    }

    @Override
	public List<Apl_arrive_receipt> findAll() {
		return dao.findAll();
	}

	@Override
	public void saveAll(List<Apl_arrive_receipt> list) {
		dao.saveAll(list);
	}
    @Override
	public ResponseDTO confirmReceipt(String code, String verifycode) {
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        // 获取当前的ip
        String ip = null;
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            ip = request.getHeader("x-forwarded-for");
        }
        // Apl_arrive_receipt receiptObj = this.dao.getByCode(code, verifycode);
        Apl_arrive_receipt receiptObj = this.dao.getByVerifycode(verifycode);

        // 1. 获取验证失败次数
        int count = this.cacheHelper.getReceiptCount(ip);
        if(count >= 5) {
            return ResponseDTO.wrap(-1, "请五分钟后再试试");
        }

        // 2. 校验
        if(null == receiptObj) {
            this.cacheHelper.setReceiptCount(ip, count + 1);
            // return ResponseDTO.wrap(-1, "输入的案号或验证码有误");
            return ResponseDTO.wrap(-1, "输入的验证码有误");
        }


        // 2.1 点击了短信链接就视为已点击
        if(St_receipt.TODELIVER == receiptObj.getStatus()) {
            this.dao.updatesStatus(receiptObj.getId(), St_receipt.CLICKED);
        }

        // 3. 校验通过查询对应关联的文件地址
        Apl_arrive_detail recordObj = this.apl_arrive_detailService.getById(receiptObj.getRecordid());
        if(null == recordObj) {
            log.error("confirmReceipt 查询送达信息失败 -> Apl_arrive_detail对象为空");
            throw new RuntimeException("查询送达信息失败");
        }
        // 3.1 判断链接是否到期
        if (ObjectUtil.isNotNull(receiptObj.getExpiredtime()) && receiptObj.getExpiredtime().before(new Date())) {
           return ResponseDTO.wrap(-1, "链接已过期");
        }
        List<Apl_arrive_material> materialList = recordObj.getMaterialList();
        if (CollectionUtil.isEmpty(materialList)) {
            log.error("confirmReceipt 查询送达文件失败 -> materialList为空");
            throw new RuntimeException("查询送达文件为空");
        }
        List<String> attchIdList = materialList.stream().map(Apl_arrive_material::getAttachid).collect(Collectors.toList());
        Map<String, Ha_attachment> ha_attachmentMap = ha_attachmentService.getHa_attachmentsByIds(attchIdList);
        List<Ha_attachment> attObj = new ArrayList<>();
        if (ObjectUtil.isNotNull(ha_attachmentMap)) {
            attchIdList.stream().forEach(attchId -> {
                attObj.add(ha_attachmentMap.get(attchId));
            });
        }
        if(ObjectUtil.isNull(attObj)) {
            log.error("confirmReceipt 查询送达文件地址失败 -> Ha_attachment对象为空");
            throw new RuntimeException("查询送达文件地址失败");
        }
        // 3.1 校验通过修改状态
        if(St_receipt.DELIVERED != receiptObj.getStatus()) {
            receiptObj.setArrivetime(new Date());
            receiptObj.setStatus(St_receipt.DELIVERED);
            this.saveOrUpdate(receiptObj);
        }

        return ResponseDTO.succData(attObj);
    }

    @Override
    public List<Apl_arrive_receipt> getReceiptById(String recordId) {
        Specification<Apl_arrive_receipt> specification = (root, query, criteriaBuilder) -> query.where(
                criteriaBuilder.and(criteriaBuilder.equal(root.get("recordid"), recordId))
        ).getRestriction();
        List<Apl_arrive_receipt> receiptList = dao.findAll(specification);
        return receiptList;
    }
}
